トップページ > Perlについて
●Perlについて●
2023-02-06 19:35:49良いコードについて:2023-02-1
さて、プログラミングでの良いコードについての記事を見つけました。
それはPythonで書かれたコードなので、Perlに書き直して、記事と合わせて載せたいと思います。
良いコードがどういうものか、というのはとても難しい問題です。様々な良さの観点があり、絶対的に良いと言えるようなコードがあるわけではありません。
しかし、良いコードには少なくとも満たしている性質がいくつか知られています。
その中の1つが、責務が整理されていることです。責務は、コード上における役割のようなものです。関心事と言われたりもします。
責務を考えるために、例えば、買い物での税込みの合計金額の算出方法を考えてみましょう。
簡単にするために、食品は消費税が8%、それ以外は10%にします。
また、小数点以下の計算は今回気にしないでいいことにしましょう。
ここで「100円のアンパンを2個、200円のペンを1本買ったら、税込みの合計はいくらか」という問題を考えてみます。
これを安直に実装するとこうなります。
# test1.pl
use strict;
my $price = &total_price();
print "Total:$price
";
sub total_price {
my $total_price = 100 * 2 * 1.08; # アンパン(2個)+消費税8%
$total_price += 200 * 1 * 1.1; # ペン(1個)+消費税10%
return $total_price;
}
total_priceサブルーチンを定義して、このコードで「100円のアンパンを2個、200円のペンを1本」を計算し、436円という値を算出しています。
ですが、これは今回限りのコードになってしまっていますね。
当然ですが、別の商品を買う度にtotal_priceサブルーチンに修正が入ってしまいます。
この実装は「税込み合計を計算する」と、「アンパン2個とペン1本の場合にその計算を行う」という2つの処理を、total_priceサブルーチンに押し込めていると言えます。
このため、商品が変われば、total_priceサブルーチンに影響が出てしまいます。あるいは、total_priceサブルーチンが具体値を知りすぎている、つまり抽象化が足りないとも言えます。
ではtotal_priceサブルーチンから、具体的な値を分離しましょう。ここで使えるのが引数ですね。
具体的な値を知る代わりに、仮引数を使って計算を行うことができます。愚直に書くとこのような実装になるかと思います。
# test2.pl
use strict;
my %syohin;
$syohin{"food1"} = 100; # アンパン1個100円
$syohin{"food2"} = 100; # アンパン1個100円
$syohin{"item1"} = 200; # ペン1個200円
my $price = &total_price(\%syohin);
print "Total:$price yen
";
sub total_price {
my $hashref = shift;
my %shina = %{$hashref};
my $total_price = 0;
my $price = 0;
foreach (keys %shina){
if($_ =~ /food/ ){
$price = $shina{$_} * 1.08; # foodは8%消費税
}elsif($_ =~ /item/ ){
$price = $shina{$_} * 1.1; # itemは10%消費税
}
$total_price = $total_price + $price;
}
return $total_price;
}
total_priceサブルーチンが随分と書き換わりました。
%syohinが商品の価格のリストで、$_が商品種別です。
これで新しい商品(例えば、カレーパン)が来たとしても、変化するのは引数の中身であって、サブルーチンを修正する必要がなくなりました。
責務の観点で言うと、total_priceサブルーチンが「税込み合計を計算する」という責務により集中できるようになったと言えます。
まだ続きます。
出典「日経クロステック 変更が難しいコードはNG、プログラミングでは「責務の分離」を意識すべし」
いいね:64 |